import java.util.LinkedList;
import java.util.Queue;

public class GameProcessor {

    // 处理用户移动
    public String[][] processMove(int x, int y, String[][] userView, int[][] mineField) {
        // 如果点击到地雷，游戏结束
        if (mineField[x][y] == -1) {
            userView[x][y] = "-1"; // 标记踩中的地雷
            return userView;
        }

        // 如果点击到非零数字，只显示该数字
        if (mineField[x][y] > 0) {
            userView[x][y] = String.valueOf(mineField[x][y]);
            return userView;
        }

        // 如果点击到0，进行广度优先搜索遍历
        if (mineField[x][y] == 0) {
            bfsReveal(x, y, userView, mineField);
        }

        return userView;
    }

    // 广度优先搜索遍历揭示区域
    private void bfsReveal(int startX, int startY, String[][] userView, int[][] mineField) {
        int size = userView.length;
        boolean[][] visited = new boolean[size][size];
        Queue<int[]> queue = new LinkedList<>();

        // 定义8个方向：上、下、左、右、左上、右上、左下、右下
        int[] dx = {-1, -1, -1, 0, 0, 1, 1, 1};
        int[] dy = {-1, 0, 1, -1, 1, -1, 0, 1};

        // 从起点开始
        queue.offer(new int[]{startX, startY});
        visited[startX][startY] = true;

        while (!queue.isEmpty()) {
            int[] current = queue.poll();
            int x = current[0];
            int y = current[1];

            // 显示当前格子的值
            userView[x][y] = String.valueOf(mineField[x][y]);

            // 如果当前格子是非零数字，停止在这个方向继续扩展
            if (mineField[x][y] > 0) {
                continue;
            }

            // 遍历8个方向
            for (int i = 0; i < 8; i++) {
                int nx = x + dx[i];
                int ny = y + dy[i];

                // 检查新坐标是否在有效范围内且未被访问过
                if (nx >= 0 && nx < size && ny >= 0 && ny < size && !visited[nx][ny]) {
                    // 只有当格子不是地雷时才加入队列
                    if (mineField[nx][ny] != -1) {
                        queue.offer(new int[]{nx, ny});
                        visited[nx][ny] = true;
                    }
                }
            }
        }
    }

    // 检查游戏是否胜利（所有非地雷格子都被揭示）
    public boolean checkWin(String[][] userView, int[][] mineField) {
        int size = userView.length;

        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                // 如果是非地雷格子且仍然被隐藏（显示为"*"），则游戏未胜利
                if (mineField[i][j] != -1 && userView[i][j].equals("*")) {
                    return false;
                }
            }
        }
        return true;
    }

    // 揭示所有地雷（游戏结束时显示）
    public String[][] revealAllMines(String[][] userView, int[][] mineField) {
        int size = userView.length;

        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                if (mineField[i][j] == -1) {
                    userView[i][j] = "X"; // 用X表示地雷
                }
            }
        }
        return userView;
    }

    // 揭示单个地雷（当踩中地雷时）
    public String[][] revealMine(int x, int y, String[][] userView, int[][] mineField) {
        userView[x][y] = "X"; // 标记踩中的地雷
        return userView;
    }

    // 获取指定位置的周围格子坐标（用于调试或扩展功能）
    public int[][] getNeighbors(int x, int y, int size) {
        int[] dx = {-1, -1, -1, 0, 0, 1, 1, 1};
        int[] dy = {-1, 0, 1, -1, 1, -1, 0, 1};

        // 计算有效的邻居数量
        int validNeighbors = 0;
        for (int i = 0; i < 8; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (nx >= 0 && nx < size && ny >= 0 && ny < size) {
                validNeighbors++;
            }
        }

        int[][] neighbors = new int[validNeighbors][2];
        int index = 0;

        for (int i = 0; i < 8; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (nx >= 0 && nx < size && ny >= 0 && ny < size) {
                neighbors[index][0] = nx;
                neighbors[index][1] = ny;
                index++;
            }
        }

        return neighbors;
    }
}